package com.lucifer.treasure.enchant.effect;

import com.mojang.serialization.MapCodec;
import com.mojang.serialization.codecs.RecordCodecBuilder;
import net.fabricmc.fabric.api.entity.event.v1.ServerLivingEntityEvents;
import net.minecraft.enchantment.EnchantmentEffectContext;
import net.minecraft.enchantment.EnchantmentHelper;
import net.minecraft.enchantment.EnchantmentLevelBasedValue;
import net.minecraft.enchantment.effect.EnchantmentEntityEffect;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EquipmentSlot;
import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.damage.DamageSource;
import net.minecraft.entity.damage.DamageTypes;
import net.minecraft.item.ElytraItem;
import net.minecraft.item.ItemStack;
import net.minecraft.particle.ParticleTypes;
import net.minecraft.server.world.ServerWorld;
import net.minecraft.util.math.Vec3d;

public record TravellerEnchantmentEffect(EnchantmentLevelBasedValue protection) implements EnchantmentEntityEffect {
    public static final MapCodec<TravellerEnchantmentEffect> CODEC = RecordCodecBuilder.mapCodec(instance ->
            instance.group(
                    EnchantmentLevelBasedValue.CODEC.fieldOf("protection").forGetter(TravellerEnchantmentEffect::protection)
            ).apply(instance, TravellerEnchantmentEffect::new)
    );

    public static void initialize() {
        // 监听伤害事件
        ServerLivingEntityEvents.ALLOW_DAMAGE.register((entity, source, amount) -> {
            return !shouldReduceDamage(entity, source);
        });

        // 监听伤害后事件来修改伤害量
        ServerLivingEntityEvents.AFTER_DAMAGE.register((entity, source, baseDamage, actualDamage, blocked) -> {
            handleDamageReduction(entity, source, baseDamage);
        });
    }

    /**
     * 检查是否应该减少伤害
     */
    private static boolean shouldReduceDamage(LivingEntity entity, DamageSource source) {
        int level = getTravellerLevel(entity);
        if (level <= 0) {
            return false;
        }

        // 检查是否是保护的伤害类型
        return isDamageTypeProtected(source);
    }

    /**
     * 处理伤害减少
     */
    private static void handleDamageReduction(LivingEntity entity, DamageSource source, float baseDamage) {
        int level = getTravellerLevel(entity);
        if (level <= 0) {
            return;
        }

        // 特殊处理坠落伤害
        if (source.isOf(DamageTypes.FALL)) {
            handleFallDamage(entity, baseDamage);
        }
    }

    /**
     * 处理坠落伤害的特殊逻辑
     */
    private static void handleFallDamage(LivingEntity entity, float baseDamage) {
        if (entity.fallDistance <= 8.0f) {
            // 8格内坠落几乎无伤
            entity.setHealth(entity.getHealth() + baseDamage - 0.1f); // 恢复大部分伤害
        } else {
            // 检查是否穿着鞘翅
            ItemStack chestplate = entity.getEquippedStack(EquipmentSlot.CHEST);
            if (chestplate.getItem() instanceof ElytraItem) {
                // 配合鞘翅时防止致命坠落
                float newHealth = entity.getHealth() + baseDamage; // 先恢复伤害
                if (newHealth <= 1.0f) {
                    // 确保至少保留1点生命值
                    entity.setHealth(1.0f);

                    // 生成烟雾粒子效果
                    if (entity.getWorld() instanceof ServerWorld serverWorld) {
                        serverWorld.spawnParticles(ParticleTypes.CAMPFIRE_SIGNAL_SMOKE,
                                entity.getX(), entity.getY() + 1.0, entity.getZ(),
                                4, // 粒子数量
                                0.5, 0.5, 0.5, // 扩散范围
                                0.02 // 初始速度
                        );
                    }
                } else {
                    // 重置为计算后的生命值
                    entity.setHealth(newHealth - baseDamage * 0.5f); // 减少50%坠落伤害
                }
            }
        }
    }

    /**
     * 检查伤害类型是否被保护
     */
    private static boolean isDamageTypeProtected(DamageSource source) {
        return source.isOf(DamageTypes.CACTUS) ||
                source.isOf(DamageTypes.FLY_INTO_WALL) ||
                source.isOf(DamageTypes.SWEET_BERRY_BUSH) ||
                source.isOf(DamageTypes.STING);
    }

    /**
     * 获取实体的Traveller附魔等级
     */
    private static int getTravellerLevel(LivingEntity entity) {
        ItemStack leggings = entity.getEquippedStack(EquipmentSlot.LEGS);
        if (leggings.isEmpty()) {
            return 0;
        }

        var enchantments = EnchantmentHelper.getEnchantments(leggings);
        return enchantments.getEnchantments().stream()
                .filter(entry -> {
                    if (entry.getKey().isPresent()) {
                        return entry.getKey().get().getValue().toString().equals("lucifer_treasure:traveller");
                    }
                    return false;
                })
                .mapToInt(entry -> enchantments.getLevel(entry))
                .max()
                .orElse(0);
    }

    @Override
    public void apply(ServerWorld world, int level, EnchantmentEffectContext context, Entity target, Vec3d pos) {
        // 主要逻辑在事件监听器中处理
        // 这里可以添加其他效果，比如粒子效果等
        if (target instanceof LivingEntity living) {
            // 可以在这里添加视觉效果
            world.spawnParticles(ParticleTypes.ENCHANT,
                    target.getX(), target.getY() + 0.5, target.getZ(),
                    3, 0.3, 0.3, 0.3, 0.01);
        }
    }

    @Override
    public MapCodec<? extends EnchantmentEntityEffect> getCodec() {
        return CODEC;
    }
} 